影片 - How to Design APIs Like a Senior Engineer (REST, GraphQL, Auth, Security)
🌐 API 基礎與設計原則
**API(應用程式介面)**是定義軟體組件間互動的合約,規範了請求(request)和回應(response)的方式,並提供一個抽象機制隱藏內部實作細節。
-
API 是客戶端(如手機或瀏覽器)與伺服器端之間溝通的橋樑。
-
API 是一種抽象化機制,例如:使用者只需透過 API 介面儲存用戶資料,而無需了解背後的邏輯。
-
API 設定了服務邊界,允許不同的系統或服務透過明確的介面互相通信(例如用戶管理與貼文管理服務分開)。
🏷️ 主要三種 API 風格
| API 風格 | 特性 | 優勢 | 適用場景 |
| RESTful API(表現層狀態轉移) | 使用 HTTP 方法(GET、POST、PUT/PATCH、DELETE)操作資源,資源以 URI 表示,無狀態 | 無狀態,每次請求自包含資訊,易於快取,結構固定且有版本控制 | 網頁與行動應用最常用,適合 CRUD 操作 |
| GraphQL | 單一端點,客戶端可指定所需資料欄位,包含查詢(query)、變更(mutation)、訂閱(subscription) | 減少多次請求,適合複雜且多變的使用者介面 | 複雜 UI 需求,避免過度或不足擷取 |
| gRPC | 高效能 RPC 框架,使用 Protocol Buffers 傳輸,支援串流與雙向通訊 | 高效能,適合微服務間內部通訊 | 伺服器間高性能通訊,微服務架構 |
REST 與 GraphQL 差異示例
| 特性 | RESTful API | GraphQL API |
| 端點數量 | 多個資源端點(如 /users, /posts) | 單一端點(如 /graphql) |
| 請求數量 | 可能需多次請求獲取相關資料 | 單次請求即可取得精確資料 |
| 回應結構 | 固定結構,版本控制(如 V1、V2) | 回應結構由客戶端指定,通常無版本控制(可對欄位版本化) |
| HTTP 方法 | GET, POST, PUT/PATCH, DELETE | 單一 POST 請求,區分 query 和 mutation |
💡 API 設計四大原則
| 原則 | 說明 | 範例說明 |
| 一致性 | 命名、格式、大小寫與設計模式需統一 | 端點命名均使用 camelCase 或 snake_case,不應混用 |
| 簡單性 | 聚焦核心用例,避免複雜設計,讓開發者易於理解 | 使 API 可在不看文件的情況下使用 |
| 安全性 | 實施驗證、授權、輸入驗證、限制請求頻率(rate limiting) | 防止未授權訪問與濫用 |
| 效能 | 使用快取、分頁、減少回傳資料大小與往返次數 | 以分頁避免一次回傳大量資料,減少頻繁多次請求 |
🔗 API 設計流程
-
需求理解:確認核心用例與使用者故事,定義範圍與邊界。
-
性能與安全需求:識別瓶頸,規劃驗證機制與頻率限制。
-
設計方法:
-
自上而下(Top-down):由高層需求定義端點與操作。
-
自下而上(Bottom-up):基於已有資料模型設計 API。
-
契約優先(Contract-first):先定義請求與回應格式,後實作。
-
-
開發與測試:本地測試後部署至階段環境,進行更多測試。
-
維護與淘汰:保持簡潔,方便維護;逐步淘汰舊版本 API。
🛠️ 應用層協定與網路協定
應用層協定簡介
-
位於網路堆疊(network stack)頂層,定義訊息格式、請求-回應模式與連線管理。
-
常見協定:HTTP、HTTPS、WebSocket、AMQP(進階訊息佇列協定)、gRPC。
HTTP / HTTPS
| 項目 | 說明 |
| HTTP | 標準的網路請求回應協定,利用方法(GET、POST、PUT、DELETE)操作資源。 |
| HTTPS | 加密版本的 HTTP,利用 TLS / SSL 證書保障資料在傳輸過程中的安全性與完整性。 |
-
請求包含方法、URL、版本、主機、身份驗證資訊。
-
回應包含狀態碼(200 成功、400 客戶端錯誤、500 伺服器錯誤)、內容類型、快取控制等。
WebSocket(即時雙向通訊)
-
解決 HTTP 輪詢導致的延遲與頻寬浪費。
-
初始握手後,建立雙向通訊通道,伺服器可主動推送資料。
-
適合即時聊天、直播等需求。
AMQP(進階訊息佇列協定)
-
支援生產者-消費者模式,確保訊息可靠傳遞。
-
消費者根據自身處理能力拉取訊息。
-
支援多種交換類型(直連、廣播、主題)。
gRPC
-
Google 發明的高效能遠端程序呼叫(RPC)框架。
-
使用 HTTP/2 傳輸,支援串流功能。
-
適合微服務內部通訊。
⚙️ 傳輸層協定:TCP 和 UDP
| 協定 | 特性 | 適用範例 | 比喻說明 |
| TCP(傳輸控制協定) | 可靠、連線導向、資料包重排序與重傳 | 付款、電子郵件、用戶資料 | 傳送包裹時需要簽收回條,保證完整送達。 |
| UDP(使用者資料報協定) | 不可靠、無連線、無重傳 | 視訊通話、線上遊戲、直播 | 郵寄明信片,不保證每張都送達,但快速且開銷小。 |
-
TCP 透過三向握手建立連線,確保資料完整且有序。
-
UDP 不保證資料到達,無連線與追蹤,速度快但有風險。
🔄 RESTful API 詳細設計
資源建模與 URL 設計
-
資源以名詞表示,非動詞,且使用複數形式。
-
URL 範例:
-
取得資源集合:
/api/products -
取得單一資源:
/api/products/{id} -
嵌套資源:
/api/products/{id}/reviews
-
-
避免使用像
/getProducts這類動詞命名。
過濾、排序與分頁
| 功能 | 方式 | 範例 |
| 過濾 | 查詢參數 | /products?category=electronics&in_stock=true |
| 排序 | 查詢參數 | /products?sort=price_asc 或 /products?sort=reviews_desc |
| 分頁 | 查詢參數 | /products?page=2&limit=10 或 /products?offset=20&limit=10 |
-
篩選能減少不必要的資料傳輸,提升效能。
-
後端負責排序,避免前端取得大量無序資料。
-
分頁避免一次回傳過多資料,常用
page+limit或offset+limit。 -
也可使用基於游標(cursor)的分頁。
HTTP 方法與 CRUD 對應
| 操作 | HTTP 方法 | URL 範例 | 特性 |
| 讀取 | GET | /products 或 /products/{id} |
安全(safe)、冪等(idempotent) |
| 建立 | POST | /products |
變更伺服器狀態,不冪等 |
| 更新(全部) | PUT | /products/{id} |
替換整個資源 |
| 更新(部分) | PATCH | /products/{id} |
部分更新資源 |
| 刪除 | DELETE | /products/{id} |
移除指定資源 |
HTTP 狀態碼使用
| 狀態碼範圍 | 說明 | 常見範例 |
| 200 系列 | 成功 | 200 OK(成功取得)、201 Created(成功建立)、204 No Content(成功但無回應內容) |
| 300 系列 | 重導向 | 301、302 |
| 400 系列 | 用戶端錯誤 | 400 Bad Request(格式錯誤)、401 Unauthorized(未授權)、404 Not Found(資源不存在) |
| 500 系列 | 伺服器錯誤 | 500 Internal Server Error |
📊 GraphQL 核心概念與設計
為什麼使用 GraphQL
-
解決 REST API 多次請求仍無法精確取得資料的痛點,減少延遲。
-
單一端點,客戶端可自訂回應資料結構。
Schema 設計與類型系統
-
Schema為客戶端與伺服器間的契約。
-
定義類型(Type),例如
User包含欄位id,name,posts。 -
類型可包含其他類型陣列,例如
Post[]。 -
支援兩大操作:
-
查詢(query):讀取資料,類似 REST 的 GET。
-
變更(mutation):新增、更新、刪除資料,類似 REST 的 POST、PUT、PATCH。
-
查詢與變更範例
query {
user(id: 123) {
name
posts {
title
}
followers {
name
}
}
}
- 客戶端指定所需欄位,避免過度取用。
錯誤處理
-
GraphQL 請求一律回傳 HTTP 200 狀態碼。
-
錯誤訊息置於回應中的
errors欄位,包含狀態碼、訊息與路徑。 -
支援部分資料回傳與錯誤共存。
設計最佳實踐
| 原則 | 說明 |
| Schema 小而模組化 | 避免過大、結構混亂 |
| 限制查詢深度 | 防止過深巢狀查詢導致效能問題 |
| 有意義命名 | 使前後端理解一致 |
| 變更使用輸入類型 | Mutation 使用 input 類型定義輸入格式 |
🔐 驗證(Authentication)基礎與方法
驗證用於確認使用者或服務的身份,是授權(Authorization)之前的第一步。
常見驗證方法
| 方法 | 機制 | 優缺點 |
| 基本驗證(Basic Auth) | HTTP 標頭帶 base64 編碼使用者名稱與密碼 | 簡單但不安全,除非搭配 HTTPS |
| 摘要認證(Digest Auth) | MD5 雜湊密碼,較基本驗證安全 | 現今較少使用,仍有安全疑慮 |
| API 金鑰(API Key) | 伺服器為客戶端產生唯一金鑰 | 易於實作但金鑰洩漏風險高,無內建過期機制 |
| Session-Based | 登入後建立伺服器端 Session,客戶端帶 Cookie | 有狀態,擴展性較差,不適合分散式系統 |
| Token-Based(Bearer Token) | 登入後發放 Token,如 JWT,客戶端每次請求帶 Token | 無狀態,擴展性好,JWT 可自含資訊與驗證 |
JWT(JSON Web Token)
-
簽名的 JSON 物件,包含用戶資訊、過期時間與權限。
-
無需每次查資料庫即可驗證。
-
常搭配 Access Token(短期)、Refresh Token(長期)使用。
-
Refresh Token 通常儲存在 HttpOnly Cookie,防止 XSS 攻擊。
🔑 授權(Authorization)模型與實作
授權決定已驗證使用者可存取哪些資源及操作。
三大授權模型
| 模型 | 說明 | 優缺點 | 範例 |
| 角色基礎存取控制(RBAC) | 使用者被分配角色,角色擁有權限集合 | 簡單易管理,但彈性較低 | GitHub:admin、editor、viewer |
| 屬性基礎存取控制(ABAC) | 根據使用者、資源屬性及環境條件決定權限 | 彈性高,但複雜且易衝突 | 如部門、時間、地點限制 |
| 存取控制清單(ACL) | 每個資源附帶使用者權限清單 | 精細控制,難以大規模擴展 | Google Drive 分享權限設定 |
OAuth 2 與 JWT 在授權中的角色
| 名稱 | 性質 | 功能 | 說明 |
| OAuth 2 | 授權框架 | 代表用戶授權第三方應用存取資源 | 不驗證身份,只授權存取範圍 |
| JWT | Token 格式 | 攜帶身份與權限資訊 | 用於系統內部授權驗證 |
🛡️ API 安全防護七大技術
| 防護技術 | 功能與說明 |
| 頻率限制(Rate Limiting) | 控制用戶在特定時間內可發送的請求數量,防止惡意攻擊與系統過載。可設定針對端點、使用者或 IP。 |
| 跨來源資源共享(CORS) | 限制瀏覽器哪些網域可呼叫 API,防止惡意網站偽裝請求。 |
| SQL / NoSQL 注入防範 | 使用參數化查詢或 ORM 保護資料庫,避免惡意輸入修改查詢語法。 |
| 防火牆 | 過濾惡意流量,阻擋異常請求。可部署於網路邊界。 |
| 虛擬私人網路(VPN) | 限制內部 API 存取範圍,僅允許同網域用戶存取。 |
| 跨站請求偽造(CSRF)防禦 | 利用 CSRF Token 防止攻擊者冒用使用者身份發送非預期請求,通常與 Session Cookie 配合使用。 |
| 跨站指令碼攻擊(XSS)防護 | 防止惡意腳本注入並執行於其他使用者瀏覽器,需對輸入進行過濾與編碼。 |
🔄 TCP 三向握手流程
-
SYN:客戶端發送連線請求。
-
SYN-ACK:伺服器確認並回應。
-
ACK:客戶端回應確認,連線建立。
此流程確保連線可靠及資料有序傳輸。
🔍 重要專有名詞定義
API(應用程式介面)
定義軟體組件互動的合約,規範請求格式、端點、方法及回應格式。
REST(表現層狀態轉移)
一種基於資源的 API 設計風格,透過標準 HTTP 方法操作資源。
GraphQL
一種 API 查詢語言,允許客戶端指定所需欄位,減少不必要資料傳輸。
gRPC
Google 推出的高效能遠端程序呼叫框架,使用 Protocol Buffers 與 HTTP/2。
JWT(JSON Web Token)
一種自包含的簽名 JSON 物件,用於驗證與授權。
OAuth 2
授權框架,允許第三方應用代表使用者存取資源。
CORS(跨來源資源共享)
瀏覽器安全機制,限制不同網域間的資源請求。
CSRF(跨站請求偽造)
攻擊方式,利用已登入使用者身份發送非預期請求。
七種保護API的安全方法:
/file-20260506210832657.png)